package com.atguigu.gmall.order.service.impl;

import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.HttpClientUtil;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.product.client.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Random;

/**
 * @Author: 李旭
 * @Time: 15:42
 * @Description:
 */
@Service
public class OrderInfoServiceImpl implements OrderInfoService {


    @Value("${ware.url}")
    private String wareUrl;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    //提交订单
    @Override
    public Long submitOrder(OrderInfo orderInfo) {

        //1:订单表
        //将订单的商品清单 根据skuId 重新加载一次
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        StringBuilder stringBuilder = new StringBuilder();
        orderDetailList.forEach(orderDetail -> {
            //防止页面被人篡改  重新查询价格
            BigDecimal price = productFeignClient.getPrice(orderDetail.getSkuId());
            orderDetail.setOrderPrice(price);
            //订单描述
            stringBuilder.append(orderDetail.getSkuNum()+" ");
        });

        //1.1 总金额  重新订算
        orderInfo.sumTotalAmount();//0元
        //1.2订单状态
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());
        //1.3 订单交易编号  (第三方)
        //必须唯一  ： 1ms 里下了多张订单  同一个交易编号  不唯一
        String outTradeNo = "ATGUIGU" + System.currentTimeMillis() + new Random().nextInt(1000);
        orderInfo.setOutTradeNo(outTradeNo);
        //1.4 订单描述
        if (null!=stringBuilder && stringBuilder.length()>100){
            //截取
            orderInfo.setTradeBody(stringBuilder.toString().substring(0,100));
        }else {
            orderInfo.setTradeBody(stringBuilder.toString());
        }

        //1.5 创建时间
        //Date curDate = new Date();
        Calendar calendar = Calendar.getInstance();
        //当前时间
        orderInfo.setCreateTime(calendar.getTime());
        //1.6 失效时间  2小时 半小时
        calendar.add(Calendar.MINUTE,30);
        //半小时之后的时间
        orderInfo.setExpireTime(calendar.getTime());
        //1.7 进度状态
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());

        //2:订单详情表  （商品清单）   由于详情表没有外键，因此也必须再遍历一遍，将skuId单独装进去，涉及到钱，不要怕麻烦
        List<OrderDetail> orderDetailList1 = orderInfo.getOrderDetailList();
        List<String> skuIds = new ArrayList<>();

        orderDetailList1.forEach(orderDetail -> {
            //订单表的主键(外键)
            orderDetail.setOrderId(orderInfo.getId());
            skuIds.add(orderDetail.getSkuId().toString());
            orderDetailMapper.insert(orderDetail);
        });

        //1）将已经生成订单的商品从购物车中删除出去  canal
        String cacheH = RedisConst.USER_KEY_PREFIX + orderInfo.getUserId() + RedisConst.USER_CART_KEY_SUFFIX;
        redisTemplate.opsForHash().delete(cacheH,skuIds.toArray());//可变参数，可以放一个集合或者数组，这样就可以实现批量操作
        //2）删除DB 同学们完成






        //TODO 取消订单   ： 提交订单开始计时 30分钟后 如果用户不支付 取消订单
        // 12306 买票  30分钟    锁定的时间
        // 查询历史订单  取消   支付 未支付
        // 定时器 （下下策）
        // （上上策）  MQ  延迟消息  30分钟之后马上发消息  执行订单的取消




        return null;
    }


    //校验库存，链接仓库
    @Override
    public boolean hasStock(Long skuId, Integer skuNum) {
        String url = wareUrl + "/hasStock?skuId="+ skuId + "&num=" + skuNum;
        return "1".equals(HttpClientUtil.doGet(url));//响应体
    }
}
